(*
  Copyright (c) 2009 Barry Schwartz

  Permission is hereby granted, free of charge, to any person
  obtaining a copy of this software and associated documentation
  files (the "Software"), to deal in the Software without
  restriction, including without limitation the rights to use,
  copy, modify, merge, publish, distribute, sublicense, and/or sell
  copies of the Software, and to permit persons to whom the
  Software is furnished to do so, subject to the following
  conditions:

  The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  OTHER DEALINGS IN THE SOFTWARE.
*)

open XNum
open UTypes
open Substitute
open FontMetric
open Dim
open Graphic
  
type index_position = | LeftIndex | RightIndex | VertIndex (* with sexp *)

type math_code =
  | NoMath
  | Ordinary
  | BinOp
  | Relation
  | Operator
  | Punct
  | Open
  | Close
  | Inner
  | SubScript
  | SuperScript
  | IndexPosition of index_position
 (* with sexp *)

type page_info = {
  pi_width     : num;
  pi_height    : num;
  pi_page_no   : int;
  pi_old_marks : (uc_string * uc_string) list;
  pi_new_marks : (uc_string * uc_string) list
} (* with sexp *)

(* basic box *)
type 'a basic_box = {
  b_width    : dim;
  b_height   : dim;
  b_depth    : dim;
  b_contents : 'a
} (* with sexp *)

(* contents of a box *)
type box = contents_type basic_box

and contents_type =
  | EmptyBox
  | CharBox of glyph_desc * font_metric * glyph_text
  | GlueBox of bool * bool       (* GlueBox (implicit, discardable) *)
  | RuleBox
  | ImageBox of string
  | CompBox of gfx_cmd list
  | MathBox of math_code * box
  | BreakBox of num * bool * box list * box list * box list
  | CommandBox of box_cmd
  | ProcBox of (page_info -> (num * num) -> box -> gfx_cmd list)

and box_cmd =
    [
    | `GfxCmd of gfx_cmd
    | `ParCmd of par_cmd
    | `PageCmd of page_cmd
    | `Special of simple_cmd
    ]

and gfx_cmd =
    (dim, box) graphic_command

and par_cmd =
  | VInsert of bool * box list
  | CallParFunction of (int -> unit)

and floating =
    (uc_string * (extended_glyph_item list))

and page_cmd =
  | SetNextLayout of uc_string
  | SetMark of uc_string * uc_string
  | CallPageFunction of (page_info -> (num * num) -> unit)
  | Float of floating

and simple_glyph_item =
    (box, box) JustHyph.simple_glyph_item

and extended_glyph_item =
    (box, box) JustHyph.extended_glyph_item

(* with sexp_of *)

type glyph_composer = (font_metric, box, box) Substitute.glyph_composer (* with sexp_of *)

val empty_box : box
val is_empty_box : box -> bool
val is_real_box : box -> bool
val new_glyph_box : glyph_desc -> font_metric -> glyph_text -> box
val new_char_box : uc_char -> font_metric -> glyph_text -> box
val is_char_box : box -> bool
val new_glue_box : dim -> dim -> bool -> bool -> box
val new_kern_box : num -> num -> box
val is_glue_box : box -> bool
val is_implicit_glue : box -> bool
val is_discardable_glue : box -> bool
val new_rule_box : dim -> dim -> dim -> box
val is_rule_box : box -> bool
val new_compound_box : dim -> dim -> dim -> gfx_cmd list -> box
val is_compound_box : box -> bool
val wrap_in_compound_box : box -> box
val add_to_compound_box : box -> gfx_cmd list -> box
val scale_box_horiz : box -> (num * int) -> box
val scale_box_vert : box -> (num * int) -> box
val scale_box_horiz_upto : box -> (num * int) -> box
val scale_box_vert_upto : box -> (num * int) -> box
val resize_box_horiz : box -> num -> box
val resize_box_vert : box -> num -> num -> box
val resize_box_horiz_upto : box -> num -> box
val resize_box_vert_upto : box -> num -> num -> box
val shift_compound_box : box -> num -> num -> box
val make_phantom : box -> box
val make_hphantom : box -> box
val make_vphantom : box -> box
val new_image_box : num -> num -> string -> box
val new_math_box : math_code -> box -> box
val is_math_box : box -> bool
val math_box_code : box -> math_code
val new_break_box : num -> bool -> box list -> box list -> box list -> box
val forced_break_box : box
val break_box_penalty : box -> num
val break_box_hyph : box -> bool
val break_box_pre : box -> box list
val break_box_post : box -> box list
val break_box_no : box -> box list
val new_command_box : box_cmd -> box
val new_proc_box : dim -> dim -> dim -> (page_info -> num * num -> box -> gfx_cmd list) -> box
val discard_glue : box list -> box list * box list
val remove_breaks : box list -> box list
val simple_item_to_box : simple_glyph_item -> box
val extended_item_to_box : extended_glyph_item -> box
val draw_box : page_info -> num -> num -> box -> simple_box
val log_box : box -> unit
val long_dump_box : box -> unit
val short_dump_box : box -> unit
val long_dump_box_list : box list -> unit
val short_dump_box_list : box list -> unit
